home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 6
/
QRZ Ham Radio Callsign Database - Volume 6.iso
/
mac
/
files
/
amiga
/
csrc720j.lzh
/
mbmail.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-14
|
65KB
|
2,873 lines
/*
* MBMAIL.C - 10/03/92 The message file stuff, except for forwarding.
*/
#include "mb.h"
#ifdef MCH_AMIGA
extern char optflags[];
extern char tmpstr[];
extern short all_number;
extern short gotmail;
extern short debug;
short thebox = 0,kambbs = 0;
extern short interflag;
extern int srcmd_flag; /* for SR */
struct lst_msg last_msg;
#endif
#define btmax 112 /* Max text in beacon line */
#define ln_hier 64
char orgmsg[6], orgbbs[7], orgtime[5], orgdate[7];
char *mbfile, *mbbfile, *msgdir, *bidfile, *stfile;
char bbidfile[] = "BID.TMP";
char *ufwd; /* Calls with unread msgs, for BT */
char *bfwd; /* Calls with unread msgs, for forwarding */
short ufwdm, ufwdn, bfwdm, bfwdn, bidnum;
short tstaleb, tstalen, tstaleu;
short tstale1, tstale2, tstale3;
short rstale1, rstale2, rstale3;
int hasbid, needbid, holdit;
char *mm[num_mm];
char wpcall[ln_call];
XBBS *xbbs;
HOLD *hold;
MAIL_HDR *mfhs;
MSG_HDR *tmmhs;
FILE *bfl;
#ifndef MCH_AMIGA
int mfl, mflb;
#else
int mfl = -1, mflb = -1;
#endif
msgfile(p, n)
char *p;
word n;
{
sprintf(p, "%s%u", msgdir, n);
}
/*
* Open file to hold BIDs
*/
opnbid()
{
#ifndef MCH_AMIGA
if ((bfl = fopen(bidfile, "a+")) is NULL) { nofile(bidfile); exit(1); }
#else
/* This does not need locking since it only opens and closes the file */
if((bfl = fopen(bidfile, "a+")) is NULL) {
nofile(bidfile);
done(1);
}
#endif
fclose(bfl);
}
/*
* Write message header.
*/
wt_mmhs()
{
if (port->mmhs->rn) write_rec (mfl, port->mmhs->rn, (char *)port->mmhs);
}
/*
* Get message title.
*/
get_title()
{
while(!getdat());
remnl(port->line);
strncpy(port->mmhs->title, port->line, mhtitl);
}
/*
* Parse the [@ bbs] and [< from] fields of a command.
*/
atfrom(i)
int i;
{
if (*port->fld[i] is '<') pcall(port->mmhs->from, port->fld[i + 1]);
else if (*port->fld[i] is '@')
{
pcall(port->mmhs->bbs, port->fld[i +1]);
if ((strchr(port->fld[i + 1], '.')) is NULL)
{ chkhier(); return; }
port->mmhs->ext = 2;
fill (port->mmhs->call, '\0', 124);
strncpy(port->mmhs->call[0], port->fld[i + 1], ln_hier);
}
}
/*
* Parse the fields of a send command.
*/
pfld()
{
#ifdef MCH_AMIGA
short life = 0; /* ARF ARF! */
short ltmp;
/* for SR command. Any SR command with one or more arguments is
an error
*/
if(port->opt2 == 'R') {
port->msg = mwhat;
return(0);
}
#endif
hasbid = false;
port->mmhs->type = port->opt2;
pcall(port->mmhs->to, port->fld[1]);
/* If a message is to an individual and type is blank,
* automatically make it a private message, else make it a bulletin.
*/
if (port->opt2 is ' ')
if (iscall(port->mmhs->to)) port->mmhs->type = 'P';
else port->mmhs->type = 'B';
strncpy(port->mmhs->from, port->user->call, ln_call);
fill(port->mmhs->bbs, ' ', ln_call);
fill(port->mmhs->bid, ' ', ln_bid);
fill(port->mmhs->fwdc, '\0', ln_call);
port->mmhs->ext = 0;
#ifdef MCH_AMIGA
/* Check the message type and do some fancy overriding where necessary */
/* In particular there's a new fix here specifically for the KAM BBS in
its V3.01 so that a personal message to an invalid callsign is forced
to be a Bulletin
*/
switch(port->mmhs->type) {
case 'P':
if(!kambbs)break;
if(!iscall(port->mmhs->to)) {
port->mmhs->type = 'B';
}
break;
/* If type is blank then set it to Personal if the 'to' is a valid
call, otherwise make it a bulletin
*/
case ' ':
if(iscall(port->mmhs->to)) {
port->mmhs->type = 'P';
}
else {
/* If the TO call is one letter long then someone is trying to send
a THEBOX control message. Throw it away.
*/
if((port->mmhs->to[1] == ' ') || (port->mmhs->to[1] == 0)) {
outstr("No - I don't use control messages\n");
needbid = 0;
return(0);
}
port->mmhs->type = 'B';
}
break;
/* THEBOX can send a 'S$' command. Set the type to Bulletin.
THEBOX only accepts an 'S' command and ignores any option
such as 'P', 'B' etc. If the message is TO a valid call
then it is marked 'P'. If it is not 'P', it will mark it
as 'B' if either there is no '@' field or if the '@' field
is a valid call. If it is not 'B' but the FROM call is
valid then it marks the message as '$'. If the TO field
is only one character long then the message is marked 'C'.
Failing all this the message is marked 'H' and is held.
*/
case '$':
port->mmhs->type = 'B';
break;
/* THEBOX can also send 'SC' which is some form of control message
that doesn't mean anything to us. Reject it.
*/
case 'C':
outstr("No - I don't use control messages\n");
needbid = 0;
return(0);
}
/* The switch may have changed the type so we have to change the
opt2 as well. They are almost the same thing.
*/
port->opt2 = port->mmhs->type;
/* Force Personal messages to require a BID .... for MID code */
if(port->mmhs->type == 'P')needbid = 1;
/* THEBOX can send us a message lifetime indicator at the end of an 'S'
command. Save the number for later use but remove the field so the
remaining code will see the bid at the end (if it is there).
*/
life = -1;
if(*port->fld[port->flds-1] is '#') {
ltmp = atoi(&port->fld[port->flds-1][1]);
if((ltmp > 0) && (ltmp < 256))life = ltmp;
port->flds--;
}
/* If this is a bulletin and the lifetime isn't set then default it.
*/
if((port->mmhs->type == 'B') && (life == -1))
life = tstaleb;
#endif
if (port->flds > 3) atfrom(port->flds - 2);
if (port->flds > 5) atfrom(port->flds - 4);
#ifdef MCH_AMIGA
/* routine added to mbuser to see if we have the user 'to' in our
user record file. If so, then use our @bbs rather than the one
in the message. We presume that if that user's name is on file
here and we also have an @bbs for him, then it is likely to
be just as accurate, or better, than the one in the message.
In particular, this is useful for setting the @bbs field when
a user leaves it out of an 'S' command.
*/
replace_bbs();
#endif
if (port->flds > 2)
if(*port->fld[port->flds-1] is '$')
{
/* MCH_AMIGA */
if (*(port->fld[port->flds - 1] + 1)/* isnt NULL*/)
{
strncpy(port->mmhs->bid, port->fld[port->flds - 1] + 1, ln_bid);
hasbid = true;
}
if (port->flds > 4) atfrom(port->flds - 3);
if (port->flds > 6) atfrom(port->flds - 5);
}
initmsg(true);
#ifdef MCH_AMIGA
/* Store the message lifetime which will be set to the '#' field of
a received message if it exists. Otherwise it will be the lifetime
default for a bulletin or zero.
*/
if(life)port->mmhs->lifetime = life;
/* Check the reject.btn file to see if this message should be
rejected.
*/
if(test_reject()) {
outstr("No - Rejected\n");
needbid = 0;
return(0);
}
/* Checks for unknown @BBS field and leaves it in tmpstr[0] if so */
/* Must not use tmpstr between here and the warning message */
ltmp = test_bbs();
#endif
if(!s_mart) {
#ifdef MCH_AMIGA
/* Part of the 'SR' command */
if(last_msg.type)prt_subj();
/* WATCH OUT .... I've bracketed this else across these two #ifdefs */
else {
if(ltmp) {
outstr("WARNING: The @BBS field '");
outstr(tmpstr);
outstr("' is not known at this BBS\n");
outstr(" Your message may not be delivered ... continue\n");
}
#endif
if (port->user->options & (u_bbs | u_expert)) outstr("Sj:\n");
else prtx(mm[0]);
#ifdef MCH_AMIGA
}
/* Part of SR command - don't call get_title */
if(last_msg.type == 0)
#endif
get_title();
#ifndef MCH_AMIGA
return;
#else
return(1);
#endif
}
else {
#ifdef MCH_AMIGA
/* Check for unwanted bulletins.
If this is a bulletin or it has a BID then see if we
want this bulletin.
If the @bbs has a corresponding
msgs/bbs.dis then accept it, otherwise No tnx
*/
if(optflags[0] && (port->mmhs->type == 'B')) {
if(tmpstr[0] == 0) {
outstr("No - Don't want it tnx\n");
needbid = 0;
return(0);
}
}
#endif
if (hasbid) {
checkbid();
if (!needbid) {
outstr("NO\n");
sprintf(port->mmhs->title, "<<%6.6s - %s>>",
port->user->call, port->fld[port->flds-1]);
wt_mmhs();
#ifndef MCH_AMIGA
return;
#else
return(0);
#endif
}
prtx("OK\n");
get_title();
#ifndef MCH_AMIGA
return;
#else
return(1);
#endif
}
else {
prtx("OK\n");
get_title();
needbid = true; /* will check and may assign one later */
#ifndef MCH_AMIGA
return;
#else
return(1);
#endif
}
}
#ifdef MCH_AMIGA
/* Not sure it can get here ... but just in case */
return(1);
#endif
}
/*
* Create the header line.
*/
makehdr()
{
register char st,ef,ht;
#ifdef MCH_AMIGA
register char *p;
#endif
st = 'N';
ht = ' ';
#ifndef MCH_AMIGA
if (port->mode & ops)
{
if (port->mmhs->stat & m_stale) st = 'O';
if (port->mmhs->stat & m_bull) st = '$';
if (port->mmhs->stat & m_hold)
{
st = 'H';
if(port->mmhs->htype) ht = port->mmhs->htype;
}
}
#endif
if (port->mmhs->stat & m_fwd) st = 'F';
if (port->mmhs->stat & m_read) st = 'Y';
if (port->mmhs->stat & m_kill) st = 'K';
if (port->mmhs->stat & m_busy) st = 'B';
#ifdef MCH_AMIGA
/* Show the sysop the true state of the messages. Doing this first means
all the other states e.g. 'Y' override these
*/
if (port->mode & ops)
{
if (port->mmhs->stat & m_stale) st = 'O';
if (port->mmhs->stat & m_bull) st = '$';
if (port->mmhs->stat & m_hold) st = 'H';
}
#endif
if (port->mmhs->ext is 2) ef = '*'; else ef = ' ';
#ifndef MCH_AMIGA
sprintf(tmp->scr,"%5u %c%c%c%5u %6.6s %6.6s %6.6s%c%3u %4.4s/%4.4s %s\n",
port->mmhs->number, port->mmhs->type, st, ht, port->mmhs->size,
port->mmhs->to,port->mmhs->from,port->mmhs->bbs,ef,port->mmhs->read,
port->mmhs->date + 2, port->mmhs->time, port->mmhs->title);
#else
/* Don't let the title exceed the line length */
sprintf(tmpstr,"%-27.27s",port->mmhs->title);
for(p=tmpstr;*p;p++);
p--;
while((p > tmpstr) && (*p == ' '))p--;
p++;
*p = 0;
sprintf(tmp->scr,"%5u %c%c%c%5u %6.6s %6.6s %6.6s%c%3u %4.4s/%4.4s %s\n",
port->mmhs->number, port->mmhs->type, st, ht, port->mmhs->size,
port->mmhs->to,port->mmhs->from,port->mmhs->bbs,ef,port->mmhs->read,
port->mmhs->date + 2, port->mmhs->time, tmpstr);
#endif
if ((port->opt2 is 'K') and (port->mode & ops))
{
if (!port->mmhs->fport) port->mmhs->fport = ' ';
sprintf(tmp->scr+37, ">%6.6s %c->%6.6s %s\n",port->mmhs->fwdd,
port->mmhs->fport, port->mmhs->fwdc, port->mmhs->title);
}
}
/*
* Write mail.dat header into text file
*/
makehdr2()
{
register char st, c;
int msfl;
char flags[mmesn];
fill (flags, ' ',mmesn);
fill (tmp->scr, '\0', 256);
tmp->scr[254] = '\r'; tmp->scr[255] = '\n';
#ifdef MCH_AMIGA
/* Save the lifetime in the header so that mbrestm can recover it */
tmp->scr[252] = port->mmhs->lifetime;
#endif
if (port->mmhs->ext is 1)
{
for (c=0; c < port->mmhs->count; c++)
flags[c] = port->mmhs->flag[c] + '0';
}
st = 'N';
if (port->mmhs->stat & m_busy) st = 'B';
if (port->mmhs->stat & m_stale) st = 'O';
if (port->mmhs->stat & m_fwd) st = 'F';
if (port->mmhs->stat & m_bull) st = '$';
if (port->mmhs->stat & m_hold) st = 'H';
if (port->mmhs->stat & m_read) st = 'Y';
if (port->mmhs->stat & m_kill) st = 'K';
sprintf(tmp->scr,
"%5u %c%c %5u %6.6s %6.6s %6.6s %6.6s %4.4s %-12.12s %5u\r\n",
port->mmhs->number, port->mmhs->type, st, port->mmhs->size,
port->mmhs->to, port->mmhs->from, port->mmhs->bbs,
port->mmhs->date, port->mmhs->time, port->mmhs->bid, port->mmhs->read);
if (port->mmhs->ext is 2)
sprintf(tmp->scr+68, "%c %s\r\n%s\r\n", port->mmhs->ext +'0',
port->mmhs->call, port->mmhs->title);
else sprintf(tmp->scr+68, "%c %13.13s \r\n%s\r\n", port->mmhs->ext +'0',
flags, port->mmhs->title);
msgfile(port->cmd, port->mmhs->number);
if ((msfl = open(port->cmd, O_WRONLY | O_BINARY)) < 0) return;
write_rec(msfl, 0, (char *)tmp->scr);
close(msfl);
}
/*
* Print a message header.
*/
char prthdr(tit, max_title)
int tit, max_title;
{
char *a, *b;
register short i;
register short docc;
#ifndef MCH_AMIGA
if (tit) prtx(mm[3]);
#else
/* If we print a title then start the line counter as well. */
if (tit) {
prtx(mm[3]);
pgst(NULL);
pgck();
}
#endif
makehdr();
if (strlen(tmp->scr) > 79)
{
if (!max_title)
{
tmp->scr[79] = '\n';
tmp->scr[80] = '\0';
}
else if (lstquit()) return ('Q');
}
outstr(tmp->scr);
if (lstquit()) return ('Q');
if((port->opt1 is 'L') and
((*port->fld[1] isnt ';') and
(*port->fld[2] isnt ';') and (*port->fld[3] isnt ';')))
return(' ');
if(*port->mmhs->fwdc) if (port->mode & ops)
{
sprintf(port->line,
" <<%6.6s F->%6.6s", port->mmhs->fwdd, port->mmhs->fwdc);
outstr(port->line);
if (!(port->mmhs->ext))
{
outchar('\n');
if (lstquit()) return ('Q');
}
}
if (port->mmhs->ext is 2)
{
outstr(" EF:");
outstr(port->mmhs->call[0]);
outchar('\n');
if (lstquit()) return ('Q');
}
if (port->mmhs->ext is 1) if (port->mode & ops)
{
docc = false;
for (i = 0; i < port->mmhs->count; i++) if (port->mmhs->flag[i])
docc = true;
if (docc)
{
outstr(" cc:");
for (i = 0; i < port->mmhs->count; i++)
{
if (port->mmhs->flag[i]) outchar(' '); else outstr(" *");
outnb(port->mmhs->call[i], ln_call);
}
outchar('\n');
if (lstquit()) return ('Q');
}
}
if (port->mode & ops) if (*port->mmhs->bid isnt ' ')
{
outstr(" BID: ");
a = port->line;
b = port->mmhs->bid;
unbl(a, b, ln_bid);
outstr(port->line); outchar('\n');
if (lstquit()) return ('Q');
}
#ifdef MCH_AMIGA
if((port->mode & ops) && (port->mmhs->type == 'B')) {
sprintf(tmpstr," Life: %u\n",port->mmhs->lifetime);
outstr(tmpstr);
if(lstquit())return('Q');
}
#endif
return(' ');
}
lstquit()
{
if ((pgck() is 'Q') or (chkdis())) return true;
return false;
}
/*
* Read the message, look for the last bbs header.
* Set the @ field of the current message to the "at bbs" in that header.
*/
findat()
{
register short i;
fill(port->mmhs->bbs, ' ', ln_call);
msgfile(port->line, port->mmhs->number);
if ((port->fl = fopen(port->line, "r")) is NULL) { nofile(port->line); return; }
fseek(port->fl, (long)RECSIZE, 0);
while(fgets(port->line, linelen, port->fl) isnt NULL)
{
if (!parsehd(port->line)) break;
pcall(port->mmhs->bbs, orgbbs);
}
fclose (port->fl);
chkhier();
}
/*
* Parse a message header line.
*/
parsehd(in)
char *in;
{
register char *p;
register int count, n;
if (!ishead(in)) return false;
p = strchr(in, 'R');
p++;
if (*p is ':') p++;
if (*p is ' ') p++;
count = 6;
n = 0;
while (*p and count--)
{
if (!isdigit(*p)) break;
orgdate[n++] = *p++;
}
orgdate[n] = '\0';
if (*p is '/') p++;
count = 4;
n = 0;
while (*p and count--)
{
if (!isdigit(*p)) break;
orgtime[n++] = *p++;
}
orgtime[n] = '\0';
if ((p = strchr(in, '@')) is NULL) return false;
{
p++;
/* skip colon or a space in @:call OR @ call */
while ((*p is ':')or(*p is ' ')) p++;
count = ln_call;
n = 0;
while (*p and count--)
{
if (!isalnum(*p)) break;
toupper(*p);
orgbbs[n++] = *p++;
}
orgbbs[n] = '\0';
}
if (((p = strrchr(in, '#')) isnt NULL) and (*(p+1) is ':'))
{
p++;
while ((*p is ':')or(*p is ' ')) p++;
count = 5;
n = 0;
while (*p and count--)
{
if (!isalnum(*p)) break;
orgmsg[n++] = *p++;
}
orgmsg[n] = '\0';
}
else
{
p = strchr(in, '@');
p--; count = 5;
while(count-- and *p isnt ' ') p--;
p++;
if (*p is '<') p++;
count = 5;
n = 0;
while (*p and count--)
{
if (*p is '@') break;
orgmsg[n++] = *p++;
}
orgmsg[n] = '\0';
}
return true;
}
/*
* Find a message given it's number.
*/
findmsg(nr)
word nr;
{
register word i;
#ifdef MCH_AMIGA
check_mail();
unlock_mail();
#endif
for (i = mfhs->last; i; i--)
{
read_rec(mfl, i, (char *)port->mmhs);
if (port->mmhs->number is nr) return true;
}
return false;
}
/*
* Create the distribution list, if required.
*/
dodis()
{
register FILE *dfl;
#ifndef MCH_AMIGA
if (port->mmhs->ext is 2) return;
port->mmhs->ext = 0;
#else
/* The code has been modified so that if ->ext is non-zero then dodis()
has already been called ( == 1) or doesn't need to be called ( == 2).
*/
if (port->mmhs->ext) return;
#endif
if (*port->mmhs->bbs is ' ') return;
unbl(tmp->scr, port->mmhs->bbs, ln_call);
strcpy(port->line, msgdir);
strcat(port->line, tmp->scr);
strcat(port->line, ".DIS");
if ((dfl = fopen(port->line, "r")) is NULL) return;
port->mmhs->ext = 1 ;
for (port->mmhs->count = 0;
(port->mmhs->count < mmesn) and (fgets(tmp->scr, scrmax, dfl) isnt NULL);
port->mmhs->count++)
{
strupr(tmp->scr);
pcall(port->mmhs->call[port->mmhs->count], tmp->scr);
#ifdef MCH_AMIGA
/* Blank lines are bad news! */
if(port->mmhs->call[port->mmhs->count][0] == ' ') {
port->mmhs->count--;
continue;
}
#endif
if(matchn(port->mmhs->call[port->mmhs->count], port->user->call, ln_call))
port->mmhs->flag[port->mmhs->count] = false;
else port->mmhs->flag[port->mmhs->count] = true;
}
fclose(dfl);
}
/*
* Do we hold this message?
*/
ishold(c)
char *c;
{
register HOLD *hp;
for (hp = hold; hp isnt NULL; hp = hp->next)
if (matchn(hp->call, c, ln_call)) return true;
return false;
}
/*
* Create message utilities - initmsg and cremsg.
* Used by "send message", "make message from file",
* "kill msg" (service messages), "copy message".
*/
initmsg(h)
int h;
{
if (s_flag & s_dv) begin_lock();
#ifdef MCH_AMIGA
check_mail();
#else
read_rec(mfl, 0, (char *)mfhs);
#endif
port->mmhs->rn = mfhs->next++;
port->mmhs->number = mfhs->next_msg++;
#ifdef MCH_AMIGA
set_mail((long)mfhs->next);
#endif
port->mmhs->stat = m_busy;
#ifndef MCH_AMIGA
strncpy(port->mmhs->date, l_date, ln_date);
strncpy(port->mmhs->time, l_time, ln_time);
#else
/* Use UTC for the file creation date. */
strncpy(port->mmhs->date, z_date, ln_date);
strncpy(port->mmhs->time, z_time, ln_time);
#endif
port->mmhs->read = 0;
port->mmhs->size = 0;
if(port->mmhs->ext isnt 2) fill(port->mmhs->call, '\0', 124);
if(h)sprintf(port->mmhs->title, "<<%6.6s -- disconnected>>",port->user->call);
pcall(port->mmhs->fwdd, port->user->call, ln_call);
#ifdef MCH_AMIGA
port->mmhs->lifetime = 0;
#endif
/*
* Clean up the file header.
*/
if (!mfhs->first) mfhs->first = port->mmhs->rn;
mfhs->last = port->mmhs->rn;
mfhs->count++;
write_rec(mfl, 0, (char *)mfhs);
wt_mmhs();
mfhs->next_msg--;
if (s_flag & s_dv) end_lock();
#ifdef MCH_AMIGA
unlock_mail();
titles();
#endif
}
cremsg()
{
register XBBS *xp;
port->mmhs->stat = 0;
#ifndef MCH_AMIGA
strncpy(port->mmhs->date, l_date, ln_date);
strncpy(port->mmhs->time, l_time, ln_time);
#else
/* Use UTC for the file creation date. */
strncpy(port->mmhs->date, z_date, ln_date);
strncpy(port->mmhs->time, z_time, ln_time);
#endif
port->mmhs->read = 0;
port->mmhs->size = filesize;
for (xp = xbbs; xp isnt NULL; xp = xp->next)
if (wcm(xp->from, port->mmhs->bbs))
{
strncpy(port->mmhs->bbs, xp->to, ln_call);
if (port->mmhs->ext is 2) port->mmhs->ext = 0;
if (wcm(xp->from, xp->to)) port->mmhs->stat setbit m_bull;
break;
}
if (ishold(port->mmhs->to))
{
port->mmhs->stat = m_hold;
port->mmhs->htype = 'T';
}
if (ishold(port->mmhs->from))
{
port->mmhs->stat = m_hold;
port->mmhs->htype = 'F';
}
if (ishold(port->mmhs->bbs))
{
port->mmhs->stat = m_hold;
port->mmhs->htype = 'B';
}
if (ishold("HUSER "))
{
if (!(port->user->options & (u_sysop|u_bbs)))
if (port->mmhs->type is 'B')
{
port->mmhs->stat = m_hold;
port->mmhs->htype = 'H';
}
}
if (holdit) port->mmhs->stat = m_hold;
if (*port->mmhs->bid isnt ' ')
{
checkbid();
if (hasbid) if (!holdit) if (needbid) putbid(true);
}
dodis();
if ((port->mmhs->ext is 1) and (*port->mmhs->bid is ' '))
{
port->mmhs->stat = m_hold;
port->mmhs->htype = 'N';
}
#ifdef MCH_AMIGA
/* If there's only one call in the distribution list and that's who the
bulletin was received from, then mark the bulletin as forwarded
*/
if((port->mmhs->ext == 1) && (port->mmhs->count == 1)) {
if(port->mmhs->flag[0] == false)
port->mmhs->stat = m_fwd;
}
#endif
wt_mmhs();
makehdr2();
if (*port->fld[port->flds-1] isnt '$') port->fld[port->flds-1] = nullstr;
sprintf(port->line, "%u %-.6s@%-.6s %s %s", port->mmhs->number,
port->mmhs->to, port->mmhs->bbs, port->fld[port->flds-1], port->mmhs->title);
log('M', port->opt1, port->opt2, port->line);
mfhs->next_msg++;
#ifdef MCH_AMIGA
titles();
#endif
}
/*
* Set up the beacon line.
*/
setfwd()
{
register char *cp, *lp;
register short i;
#ifdef MCH_AMIGA
all_number = 0;
gotmail = 0;
#endif
bldfwd();
#ifndef MCH_AMIGA
if (ufwdm > 1)
{
strcpy(port->line, "BT Mail for:");
cp = ufwd;
lp = port->line + strlen(port->line);
#else
/* ufwdm > 1 is a bug. ufwdm is the MAX # of permitted callsigns.
It should be ufwdn > 0 which checks for actual number of callsigns.
I have also moved the strcpy and the alltnc() outside the 'if'
so that the beacon text is changed if there is no mail. The problem
that can occur is that if there is currently one call in the btext
and then that mail is read, then there is now no call in the btext
but the original code doesn't change the BText to a null.
*/
strcpy(port->line, "BT Mail for:");
cp = ufwd;
lp = port->line + strlen(port->line);
if(ufwdn > 0) {
/* Does sysop have mail? */
for(i=0;i<ufwdn;i++) {
if(matchn(&ufwd[i*ln_call],cport->user->call,ln_call)) {
gotmail++;
break;
}
}
#endif
while ((cp < ufwd + ln_call * ufwdn) and (lp < port->line + btmax))
{
*lp++ = ' ';
for (i = 0; i < ln_call; i++, cp++) if (*cp isnt ' ') *lp++ = *cp;
}
#ifndef MCH_AMIGA
*lp++ = '\n';
*lp = '\0';
alltnc(port->line);
}
#else
}
if(lp < port->line + btmax) {
/* If there's room, add ALL(N) on the end */
if(all_number) {
sprintf(tmpstr," ALL(%d)",all_number);
strcpy(lp,tmpstr);
lp += strlen(tmpstr);
}
}
/* store LF at the end of the beacon command */
*lp++ = '\n';
*lp = '\0';
alltnc(port->line);
/* setfwd may find that sysop has mail so call titles just in case */
titles();
#endif
}
/*
* General permission check: sysop or TO or FROM.
*/
permit()
{
if (port->mmhs->stat & (m_kill | m_busy)) return false;
if (matchn(port->user->call, port->mmhs->to, ln_call) and
!(port->mmhs->stat & m_hold)) return true;
if (matchn(port->user->call, port->mmhs->from, ln_call)) return true;
return false;
}
/*
* Return true if user has kill permission for current message.
*/
kpermit()
{
if (port->mmhs->stat & m_kill) return false;
if (port->mode & ops) return true;
if (permit()) return true;
return ((port->mmhs->type is 'T') and (port->opt2 is 'T'));
}
/*
* Return true if user has list permission for current message.
*/
lpermit()
{
if (port->user->options & u_sysop) return true;
if (permit()) return true;
#ifdef MCH_AMIGA
/* Users should be able to list a bulletin that has been forwarded.
I did it this way, rather than remove the m_fwd from the final
return statement, to avoid any unknown side-effects
*/
if((port->mmhs->type == 'B') && (port->mmhs->stat & m_fwd))return(true);
#endif
return ((port->mmhs->type isnt 'P')
and !(port->mmhs->stat & (m_fwd | m_kill | m_busy | m_hold)));
}
/*
* Return true if user has read permission for current message.
*/
rpermit()
{
if ( port->mode & ops) return true;
if (permit()) return true;
return (port->mmhs->type isnt 'P');
}
/*
* Clean the mail file.
* Force drain of buffers, update of directory item.
*/
clnmsg()
{
#ifdef MCH_AMIGA
lock_mail();
#endif
close(mfl);
mfl = open(mbfile, O_RDWR | O_BINARY);
#ifdef MCH_AMIGA
unlock_mail();
#endif
}
/*
* Close the mail file.
*/
clsmsg()
{
#ifdef MCH_AMIGA
if(mfl >= 0)
#endif
close (mfl);
}
/*
* Open the mail file.
*/
opnmsg()
{
register char *tp;
/*
* Allocate space for the mail file records.
*/
mfhs = (MAIL_HDR *) malloc(sizeof(MAIL_HDR));
tmmhs = (MSG_HDR *) malloc(sizeof(MSG_HDR));
/*
* Allocate the "who has mail" lists.
*/
ufwd = (char *) malloc (ln_call * ufwdm);
bfwd = (char *) malloc (ln_call * bfwdm);
#ifndef MCH_AMIGA
if (bfwd is NULL) errall();
#else
if (bfwd is NULL) errall(1);
#endif
/*
* Open the file. If it does not exist, make one.
*/
#ifdef MCH_AMIGA
lock_mail();
#endif
if ((mfl = open(mbfile, O_RDWR | O_BINARY)) < 0)
{
if ((mfl = open(mbfile, O_CREAT | O_RDWR | O_BINARY, pmode)) < 0)
#ifndef MCH_AMIGA
{ nofile(mbfile); exit(1); }
#else
{
nofile(mbfile);
#ifdef MCH_AMIGA
unlock_mail();
#endif
done(1);
}
#endif
inithdr();
mfhs->next_msg = 1;
#ifdef MCH_AMIGA
titles();
#endif
write_rec(mfl, 0, (char *)mfhs);
}
/*
* Read the mail file header.
*/
read_rec(mfl, 0, (char *)mfhs);
#ifdef MCH_AMIGA
unlock_mail();
#endif
/*
* If wrong version mail file, quit now.
*/
if (mfhs->version isnt mb_version)
{
#ifndef MCH_AMIGA
printf("Expected version %d, got version %d\n",
mb_version, mfhs->version);
#else
sprintf(tmpstr,"Expected version %d, got version %d\n",
mb_version, mfhs->version);
ttputs(tmpstr);
#endif
nofile(mbfile);
#ifndef MCH_AMIGA
exit(1);
#else
done(1);
#endif
}
}
/*
* Initialize the mail file header.
*/
inithdr()
{
#ifdef MCH_AMIGA
set_mail(1L);
#endif
mfhs->next = 1;
mfhs->first = 0;
mfhs->last = 0;
mfhs->version = mb_version;
mfhs->free = 0;
mfhs->count = 0;
mfhs->unt_msg = 1;
#ifdef MCH_AMIGA
titles();
#endif
curtim();
strncpy(mfhs->date, l_date, ln_date);
strncpy(mfhs->time, l_time, ln_time);
fill(mfhs->unu, '\0', mfhsunu);
}
/*
* Open mail file and read first record.
*/
readmsg()
{
#ifdef MCH_AMIGA
lock_mail();
#endif
mfl = open(mbfile, O_RDWR | O_BINARY);
read_rec(mfl, 0, (char *)mfhs);
#ifdef MCH_AMIGA
unlock_mail();
#endif
}
/*
* Does this station want us to send BIDs ?
*/
isbid()
{
register char *f;
/* Is this a sid? It must have a '-' and end with a ']' */
if ((port->line[strlen(port->line) - 2] isnt ']' ) or
((f = strrchr(port->line, '-')) is NULL))
return;
#ifdef MCH_AMIGA
/* Look for THEBOX */
if(matchn(&port->line[1],"THEBOX",6) ||
matchn(&port->line[1],"DL5UY",5))
thebox = 1;
/* Look for the newer KAM BBS which can handle BBS mail */
/* The KAM wouldn't need to be specifically recognized except that
it only allows sending personal messages. So if someone sends
a personal meesage to ALL @ ALLCAN it ought to be a bulletin.
The program will change such personal messages to bulletins.
*/
if(matchn(&port->line[1],"KAM",3)) kambbs = 1;
#endif
/* Look for special characters in the last field. */
f++;
for (; *f isnt ']';f++)
switch(*f)
{
case 'H' : s_mart setbit hidok; break;
case '$' : s_mart setbit bidok; break;
#ifdef MCH_AMIGA
case 'F' : s_mart setbit fbbok; break;
case 'B' : s_mart setbit cmpok; break;
case 'M' : s_mart setbit midok; break;
#ifdef MCH_ZOO
/* I was trying to get C-BBS to use the zoo compression routines instead of
the lzhuf from FBB. But with no success so far.
*/
case 'Z' : s_mart setbit zoook; break;
#endif
#endif
}
#ifdef MCH_AMIGA
/* If both B and Z are set then Z overrides (Z is better) */
if((s_mart & (cmpok|zoook)) == (cmpok|zoook)) {
s_mart clrbit cmpok;
}
/* If FBB compression bit is set but FBB itself is not, then clear the
compression
If option #C is selected force the compression off anyway.
*/
if((s_mart & (fbbok|cmpok)) == cmpok)s_mart clrbit cmpok;
if(!optflags[2])s_mart clrbit cmpok;
#endif
}
/*
* Check to see whether we already have this BID.
*/
checkbid()
{
FILE *out;
char *a, *b;
if(*port->mmhs->bid is ' ') {
needbid = true;
return;
}
#ifdef MCH_AMIGA
lock_bid();
#endif
if((out = fopen(bidfile, "r")) is NULL) {
#ifdef MCH_AMIGA
unlock_bid();
#endif
nofile(bidfile); return;
}
while(fgets(port->line, linelen, out) isnt NULL) {
/* the first 4 characters are the date */
strcpy(port->cmd, port->line + 4);
a = port->cmd;
remnl(a);
a = port->line;
b = port->mmhs->bid;
unbl(a, b, ln_bid);
if(match(port->cmd, port->line)) {
needbid = false;
fclose(out);
#ifdef MCH_AMIGA
unlock_bid();
#endif
return;
}
}
needbid = true;
fclose(out);
#ifdef MCH_AMIGA
unlock_bid();
#endif
}
putbid(y)
int y;
{
FILE *out;
char *a, *b;
#ifdef MCH_AMIGA
lock_bid();
#endif
if ((out = fopen(bidfile, "a")) is NULL)
{
#ifdef MCH_AMIGA
unlock_bid();
#endif
port->msg = mcant; return;
}
a = port->cmd;
if (y) b = port->mmhs->bid; else b = tmp->scr;
unbl( a, b, ln_bid);
sprintf (port->line, "%4.4s%s\n", port->mmhs->date+2, port->cmd);
if (s_flag & s_dv) begin_lock();
fputs(port->line, out);
if (s_flag & s_dv) end_lock();
fclose(out);
#ifdef MCH_AMIGA
unlock_bid();
#endif
}
/****************************************
* *
* Code for the commands starts here *
* *
****************************************/
/*
* GM or GR command: backup the mail file.
*/
untmsg()
{
register word inhdr, me;
if (port->opt2 isnt 'A') { if (sure()) return false; }
if (!mfhs->count) { port->msg = mm[5]; return false; }
prtx(mm[6]);
close(mfl); /* Close current. */
unlink(mbbfile); /* Delete backup */
/*
* Copy current to backup.
*/
if (samedir(mbfile, mbbfile)) rename(mbfile, mbbfile);
else copy(mbfile, mbbfile, false);
unlink(mbfile); /* Delete current. */
/*
* Open new current and backup.
*/
mfl = open(mbfile, O_CREAT | O_RDWR | O_BINARY, pmode);
mflb = open(mbbfile, O_RDONLY | O_BINARY);
read_rec(mflb, 0, (char *)mfhs);
me = mfhs->last;
inhdr = mfhs->first;
inithdr();
if (port->opt2 is 'R')
{
if (port->flds is 1) mfhs->next_msg = 1;
else mfhs->next_msg = atoi(port->fld[1]);
}
while(inhdr <= me) /* For each message header ... */
{
read_rec(mflb, inhdr, (char *)port->mmhs); /* Read the header. */
/*
* Tell the sysop about this message.
*/
sprintf(port->line, "%c %6u Size %6u # %6u Read %6u", port->mmhs->type,
inhdr, port->mmhs->size, port->mmhs->number, port->mmhs->read);
outstr(port->line);
inhdr++;
if (!(port->mmhs->stat & ( m_kill | m_busy)))
{
outstr("\n");
/*
* If renumbering messages, renumber this message.
*/
if (port->opt2 is 'R')
{
msgfile(port->line, port->mmhs->number);
msgfile(port->cmd, mfhs->next_msg);
rename(port->line, port->cmd);
port->mmhs->number = mfhs->next_msg++;
}
/*
* Write the header.
*/
port->mmhs->rn = ++mfhs->count;
wt_mmhs();
}
else arcmsg();
}
/*
* Write the file header.
*/
if (mfhs->count) mfhs->first = 1;
mfhs->next = mfhs->count + 1;
#ifdef MCH_AMIGA
set_mail((long)mfhs->next);
#endif
mfhs->last = mfhs->count;
mfhs->unt_msg = mfhs->next_msg;
write_rec(mfl, 0, (char *)mfhs);
close(mflb);
clnmsg();
#ifdef MCH_AMIGA
titles();
#endif
return(true);
}
/*
* Print headers of unread messages for this user.
*/
newmsg()
{
if (findfwd(port->user->call, ufwd, ufwdn) or
findfwd(port->user->call, bfwd, bfwdn))
{
prtx(mm[2]);
port->opt2 = '\0';
port->flds = 1;
lstmsg();
}
}
/*
* L command, list messages.
*/
lstmsg()
{
register short done, ok;
word h, found, more, start;
int max_title;
#ifdef MCH_AMIGA
int quote;
quote = 0;
interflag = 0;
#endif
if(port->mode & ops) max_title = false;
else max_title = true;
/*
* First set up arguments.
*/
found = 0; more = 0; done = false;
#ifndef MCH_AMIGA
if ((*port->fld[1] is ';')or(*port->fld[2] is ';')or(*port->fld[3] is ';'))
#else
/* The ';' must be the last thing on the line if it is there.
The previous argument can be a quoted string to do a search of
the title of those articles that otherwise qualify.
*/
if(*port->fld[port->flds-1] is ';')
#endif
{ port->flds--; max_title = true; }
#ifdef MCH_AMIGA
/* If the last argument is a quoted string, remember where it is but
pretend to remove it
*/
if(*port->fld[port->flds-1] is '"') {
quote = --port->flds;
}
#endif
switch(port->opt2)
{
case '@' :
case '<' :
case '>' : pcall(tcall, port->fld[1]); break;
case 'S' : if (port->flds is 1) {port->msg = mwhat; return;}
case '\0': break;
case 'E' :
case ' ' : if (port->flds is 1) more = port->user->msg_number;
default :
if (port->flds > 1)
{
if (!num(port->fld[1])) { port->msg = mwhat; return; }
more = atoi(port->fld[1]);
}
if (port->flds is 3)
{
if (!num(port->fld[2])) { port->msg = mwhat; return; }
start = atoi(port->fld[2]);
}
}
/*
* Log it, unless is initial login check for msgs.
*/
if (port->opt2)
{
sprintf(port->line, "%u", more);
log('M', 'L', port->opt2, port->line);
}
/*
* Paw through the messages and show what requested.
*/
#ifdef MCH_AMIGA
check_mail();
unlock_mail();
#endif
for (h = mfhs->last; h and !done; h--)
{
read_rec(mfl, h, (char *)port->mmhs);
if ((port->opt2 is 'L') or ((port->opt2 is 'E') and (port->flds is 2)))
done = (found is more); else done = (port->mmhs->number < more);
ok = !done;
if (port->flds is 3) if (ok)
ok = (port->mmhs->number <= start);
/*
* Does this user have read permission for this message?
*/
if (ok) ok = lpermit();
if (ok) if (port->mmhs->stat & m_kill)
ok=((port->opt2 is 'K')or(port->opt2 is 'E')or(port->opt2 is 'S'));
if (ok) if (port->mmhs->stat & m_busy) ok = (port->opt2 is 'E');
/*
* Is this message wanted?
*/
if (ok) switch(port->opt2)
{
case '\0': ok = matchn(port->user->call, port->mmhs->to, ln_call); break;
case 'E' : break;
case 'K' : ok = (port->mmhs->stat & m_kill); break;
case 'F' : ok = (port->mmhs->stat & m_fwd); break;
case 'H' : ok = (port->mmhs->stat & m_hold); break;
case 'L' : break;
case 'M' : ok = matchn(port->user->call, port->mmhs->to, ln_call);
if (!ok) ok = matchn(port->user->call, port->mmhs->from, ln_call);
break;
case 'O' : ok = (port->mmhs->stat & m_stale); break;
#ifdef MCH_AMIGA
/* Fix up strlen in 2 calls to search() .*/
#endif
case 'S' : ok = (search(strupr(port->mmhs->title), port->fld[1],
(short)strlen(port->fld[1]))or search(port->mmhs->to,
port->fld[1],(short) strlen(port->fld[1]))); break;
case 'U' : ok = !((port->mmhs->type is 'B')or(port->mmhs->type is 'A')
or (port->mmhs->stat & (m_fwd | m_read))); break;
case 'Y' : ok = (port->mmhs->stat & m_read); break;
#ifndef MCH_AMIGA
case '@' : ok = matchn(tcall, port->mmhs->bbs, ln_call); break;
case '<' : ok = matchn(tcall, port->mmhs->from, ln_call); break;
case '>' : ok = matchn(tcall, port->mmhs->to, ln_call); break;
#else
/* Permit a wildcard in these three forms of the 'L' command */
/* wmatch is in dir.c */
case '@' : ok = wmatch(port->mmhs->bbs ,tcall); break;
case '<' : ok = wmatch(port->mmhs->from,tcall); break;
case '>' : ok = wmatch(port->mmhs->to ,tcall); break;
#endif
default : ok = ((port->mmhs->type is port->opt2) or
(port->opt2 is ' '));
}
#ifdef MCH_AMIGA
if(ok && quote) {
/*
If there was a quoted string in the argument list,
check to see if it occurs in the title. If not,
then ignore it. (umatch is in dir.c)
*/
if(!umatch(&port->mmhs->title[0],port->fld[quote]))ok = 0;
}
if(interflag && (port != cport)) {
return;
}
#endif
if (ok) if (prthdr(!found++, max_title) is 'Q') return;
}
if (!found) port->msg = mfind;
s_flag setbit s_update;
}
/*
* CM command: duplicate a message.
*/
dupmsg()
{
word tmpsize;
if (!findmsg(atoi(port->fld[2]))) { port->msg = mnmsg; return; }
port->opt1 = 'S';
prthdr(true, true);
pcall(port->mmhs->to, port->fld[1]);
fill(port->mmhs->bbs, ' ', ln_call);
port->mmhs->ext = 0;
if (port->flds > 3) atfrom(port->flds - 2);
if (port->flds > 5) atfrom(port->flds - 4);
tmpsize = port->mmhs->size;
#ifdef MCH_AMIGA
/* Override @bbs if the user is on file */
replace_bbs();
#endif
msgfile(port->cmd, port->mmhs->number);
initmsg(false);
msgfile(port->line, mfhs->next_msg);
copy(port->cmd, port->line, false);
filesize = tmpsize;
cremsg();
}
/*
* F command: copy a message to a file.
*/
filmsg()
{
register char *p;
register short hdr, append, inhdr;
register FILE *out;
if (!findmsg(atoi(port->fld[1]))) { port->msg = mnmsg; return; }
hdr = true;
append = false;
inhdr = false;
if (port->flds is 4) for (p = port->fld[3]; *p; p++) switch (*p)
{
case 'A' : append = true; break;
case 'N' : hdr = false; break;
case 'I' : inhdr = true; break;
default: ;
}
if (port->opt2 is ' ') strcpy(port->line, port->fld[2]);
else if (getdir(port->fld[2]) is NULL) { port->msg = mndir; return; }
if (append) out = fopen (port->line, "a"); else
{
if ((out = fopen (port->line, "r")) isnt NULL)
{ fclose(out); port->msg = mexst; return; }
out = fopen (port->line, "w");
}
if (out is NULL) { port->msg = mcant; return; }
sprintf(tmp->scr, "%s %s", port->fld[1], port->line);
log('M', 'D', port->opt2, tmp->scr);
prthdr(true, true);
if (hdr) fputs(tmp->scr, out);
msgfile(port->cmd, port->mmhs->number);
if ((port->fl = fopen(port->cmd, "r")) is NULL)
{ fclose(out); nofile(port->cmd); return; }
fseek( port->fl, (long)RECSIZE, 0);
while (fgets(tmp->scr, linelen, port->fl) isnt NULL)
{
if (!inhdr)
{
if (!parsehd(tmp->scr)) fputs(tmp->scr, out);
}
else
fputs(tmp->scr, out);
}
fclose(port->fl);
fclose(out);
}
/*
* Upload the message text file.
*/
uloadm(tname)
char *tname;
{
register char *tp;
register PORTS *p;
short first, head;
char *a, *b;
#ifdef MCH_AMIGA
register int i;
char orgcall[7];
#endif
orgbbs[0] = '\0';
p = port;
if ((p->fl = fopen(tname, "w")) is NULL) { p->msg = mcant; return false; }
fill(tmp->scr, '.', RECSIZE);
tmp->scr[256] = '\0';
fputs( tmp->scr, p->fl);
first = true;
head = true;
filesize = 0;
while (true)
{
while(!getdat());
/*
* If user disconnected, timed out, or forced off, zap the file.
*/
if (p->mode & gone)
{
fclose(p->fl);
return false;
}
if (head)
{
if (!parsehd(p->line)) head = false;
else
/* If this is a ping-pong message */
if (s_param & s_ping)
{
a = p->cmd;
b = cport->user->call;
unbl(a, b, 6);
if (matchn(orgbbs, p->cmd, ln_call))
{
holdit = true;
port->mmhs->htype = 'P';
}
}
#ifdef MCH_AMIGA
/* Check each R: line in the bulletin header. If the BBS call is in our
distribution list for this bulletin, then mark them as already having
received the bulletin.
*/
if(head && p->mmhs->ext == 1) {
pcall(orgcall,orgbbs);
for(i = 0;i < p->mmhs->count; i++) {
if(p->mmhs->flag[i]) {
if(matchn(orgcall,p->mmhs->call[i],ln_call)) {
p->mmhs->flag[i] = false;
break;
}
}
}
}
#endif
}
/*
* If the first line is not a header (thus it is a human entering
* the message), make sure there is an initial blank line before
* the body of the message.
*/
if (first)
{
first = false;
if (*orgbbs is '\0') if (*p->line isnt '\n') fputs("\n", p->fl);
}
/*
* Stuff the line into the file.
*/
if (match(p->line, "/EX\n") or match(p->line,"/ex\n"))
{
fclose(p->fl);
return true;
}
if ((tp = strchr(p->line, cpmeof)) is NULL)
{
filesize += strlen(p->line);
fputs(p->line, p->fl);
}
else
{
if (tp isnt p->line)
{
*tp++ = '\n';
*tp = '\0';
filesize += strlen(p->line);
fputs(p->line, p->fl);
}
fclose(p->fl);
return true;
}
}
}
/*
* "Display the message text" utility.
*/
dloadm(sh)
short sh;
{
short first;
sprintf(port->line, "%u", port->mmhs->number);
log('M', 'R', port->opt2, port->line);
port->mmhs->read++;
if (matchn(port->user->call, port->mmhs->to, ln_call))
port->mmhs->stat setbit m_read;
if (port->mmhs->ext is 1)
if (matchn(port->user->call, port->mmhs->call[0], ln_call))
{
markdis(0);
port->mmhs->stat clrbit m_hold;
}
wt_mmhs();
makehdr2();
prthdr(true, true);
msgfile(port->line, port->mmhs->number);
if ((port->fl = fopen(port->line, "r")) is NULL)
{ nofile(port->line); return; }
#ifdef MCH_AMIGA
/* Code to save the information that will allow the Send Reply command
to construct a proper reply to this message. At the moment a reply
is permitted only for personal messages addressed to the reader.
(I'm not sure that this test is needed, but play it safe).
REMOVED until I have the SR command working properly.
*/
#ifdef MCH_SR
if(port->mmhs->type == 'P') {
/* matchn(port->user->call,port->mmhs->to,ln_call)) { */
last_msg.type = 'P';
unbl(last_msg.from,port->mmhs->from,ln_call);
unbl(last_msg.bbs,port->mmhs->bbs,ln_call);
strncpy(last_msg.title,port->mmhs->title,mhtitl);
}
else last_msg.type = 0;
#else
last_msg.type = 0;
#endif
/* Start the line counter */
pgst(NULL);
#endif
fseek( port->fl, (long)RECSIZE, 0 );
pgck(); /* First line of header */
pgck(); /* Second line of header */
pgck(); /* Path line */
if (port->mmhs->ext) pgck();
if (*port->mmhs->bid isnt ' ') pgck();
strcpy(tmp->scr, " Path: ");
first = true;
#ifdef MCH_AMIGA
interflag = 0;
#endif
while(fgets(port->line, linelen, port->fl) isnt NULL)
{
#ifdef MCH_AMIGA
if(interflag && (port != cport)) {
break;
}
#endif
if (!sh)
{
sh = !parsehd(port->line);
if (sh)
{
if (!first)
{
strcat(tmp->scr, "\n\n");
outstr(tmp->scr);
pgck();
prtx("Date: $j/$k\n"); pgck();
prtx("From: $P @ $a\n"); pgck();
prtx("Message-Id: <$m@$a>\n"); pgck();
prtx("To: $G @ ");
if (*port->mmhs->bbs is ' ') prtx("$O\n");
else if (port->mmhs->ext is 2) prtx("$h\n");
else prtx("$A\n"); pgck();
prtx("Subject: $E\n\n"); pgck();
}
}
else
{
if (!first) strcat(tmp->scr, "!");
strcat(tmp->scr, orgbbs);
first = false;
}
}
if (sh)
{
outstr(port->line);
if (lstquit()) { fclose(port->fl); return; }
}
}
fclose (port->fl);
}
/*
* RM command: read my messages.
*/
rdmsgm()
{
register short found;
register word h;
found = false;
#ifdef MCH_AMIGA
check_mail();
unlock_mail();
#endif
for (h = mfhs->first; h and h <= mfhs->last; h++)
{
read_rec(mfl, h, (char *)port->mmhs);
if ((!(port->mmhs->stat & (m_read|m_kill|m_fwd|m_hold|m_busy)) and
(matchn(port->user->call, port->mmhs->to, ln_call))) or
(!(port->mmhs->stat & (m_read|m_kill|m_fwd|m_busy)) and
(port->mmhs->ext is 1) and
matchn(port->user->call, port->mmhs->call[0], ln_call) and
port->mmhs->flag[0]))
{
dloadm(port->mode & ops);
found = true;
if (pause() is 'Q') return;
}
}
if (!found) port->msg = mfind;
}
/*
* R command: read one message.
*/
rdmsg()
{
char sn[6];
if ((strlen(port->fld[1]) > 5) or (!num(port->fld[1])))
{
port->msg = mwhat;
return;
}
strcpy(sn, port->fld[1]);
if (!findmsg(atoi(port->fld[1]))) { port->msg = mnmsg; return; }
if (!rpermit()) { port->msg = mprot; return; }
dloadm(port->opt2 is 'H');
if ((port->mmhs->type is 'T')and(!(port->mmhs->stat&(m_busy|m_kill|m_fwd))))
{
outstr("\nAre you going to deliver this message (Y/N)?\n");
while (!getdat());
if(toupper(*port->line) is 'Y')
{
port->opt2 = 'T';
strcpy(port->fld[1], sn);
sprintf(port->line, "KT %s\n", sn);
outstr(port->line);
klmsg();
}
}
}
/*
* KF, KM, KO, KY, KK commands, kill multiple messages.
*/
klmsgm()
{
register short ok;
register short found;
word h, next;
if (port->flds is 2) pcall(tcall, port->fld[1]);
#ifdef MCH_AMIGA
check_mail();
unlock_mail();
#endif
found = false;
for (h = mfhs->first; h and h <= mfhs->last; h++)
{
read_rec(mfl, h, (char *)port->mmhs);
ok = kpermit();
if (ok) ok = !(port->mmhs->stat & m_hold);
if (ok) if (port->flds is 2) ok = matchn(tcall, port->mmhs->to, ln_call);
if (ok) switch(port->opt2)
{
case 'F' : ok = (port->mmhs->stat & m_fwd); break;
case 'M' :
ok = ((port->mmhs->stat & m_read) and
matchn(port->user->call, port->mmhs->to, ln_call));
break;
case 'O' : ok = (port->mmhs->stat & m_stale); break;
case 'Y' : ok = (port->mmhs->stat & m_read); break;
}
if (ok)
{
sprintf(port->line, "%u", port->mmhs->number);
log('M', 'K', port->opt2, port->line);
prtx(mm[7]);
found = true;
port->mmhs->stat setbit m_kill;
write_rec(mfl, port->mmhs->rn, (char *)port->mmhs);
makehdr2();
}
}
#ifdef MCH_AMIGA
titles();
#endif
if (!found) port->msg = mfind;
}
klmult()
{
mult(false);
}
rdmult()
{
mult(true);
}
/*
* Handling multiple messages.
*/
mult(x)
int x;
{
static char msgn[25];
int i;
strncpy(&msgn[0], port->fld[2], 5);
strncpy(&msgn[6], port->fld[3], 5);
strncpy(&msgn[12], port->fld[4], 5);
strncpy(&msgn[18], port->fld[5], 5);
if (x) rdmsg();
else
{
outstr(port->fld[1]);
klmsg();
}
prtx(port->msg);
for ( i=0; msgn[i]; i += 6)
{
strcpy(port->fld[1], &msgn[i]);
if (x) rdmsg();
else
{
outstr(port->fld[1]);
klmsg();
}
prtx(port->msg);
port->msg = NULL;
}
}
/*
* K command, kill a message.
*/
klmsg()
{
register short dosvc;
unsigned int org_num;
if (!num(port->fld[1])) { port->msg = mwhat; return; }
if (!findmsg(atoi(port->fld[1]))) { port->msg = mnmsg; return; }
if (port->mmhs->stat & m_kill) { port->msg = mnmsg; return; }
if (!kpermit()) { port->msg = mprot; return; }
log('M', 'K', port->opt2, port->fld[1]);
dosvc = (port->opt2 is 'T') and
(port->mmhs->type is 'T') and
(s_param & s_svc);
if (dosvc) org_num = atoi(port->fld[1]);
/*
* Marked the message as Killed.
*/
if(port->opt2 is 'A') port->mmhs->stat setbit m_noarc;
port->mmhs->stat setbit m_kill;
write_rec(mfl, port->mmhs->rn, (char *)port->mmhs);
makehdr2();
/*
* If this is KT of T type message, and we do service messages,
* do the service message.
*/
if (dosvc)
{
port->mmhs->ext = 0;
findat();
port->opt1 = 'S';
strncpy(port->mmhs->to, port->mmhs->from, ln_call);
strncpy(port->mmhs->from, cport->user->call, ln_call);
port->mmhs->type = 'P';
fill(port->mmhs->bid, ' ', ln_bid);
initmsg(false);
msgfile(port->line, mfhs->next_msg);
port->fl = fopen(port->line, "w");
fseek(port->fl, (long)RECSIZE, 0);
fprintf(port->fl, "Msg %5u taken from %6.6s by %6.6s at %4.4s on %6.6s\n",
org_num, cport->user->call, port->user->call, l_time, l_date);
fclose(port->fl);
filesize = 56;
cremsg();
}
port->msg = mdone;
#ifdef MCH_AMIGA
titles();
#endif
}
/*
* S command: send a message.
*/
sndmsg()
{
char *a, *b;
holdit = false; /* initialize it to something */
#ifndef MCH_AMIGA
pfld();
#else
if(srcmd_flag == 0)last_msg.type = 0;
/* If there's an error in the command then return */
if(pfld() == 0)return;
/* Initialize ->ext to zero so that dodis() will detect that sndmsg has
already done it and then cremsg won't redo it. This is so that the
uloadm routine can use parsehd() to see if an incoming bulletin has
already been seen by other BBS in the distribution list and then we
won't have to send it to them.
The only other call to dodis() previously sets ->ext to zero.
*/
if(port->mmhs->ext != 2)port->mmhs->ext = 0;
dodis();
#endif
if (!isalnum(*port->mmhs->to))
{
holdit = true;
port->mmhs->htype = 'C';
}
if (port->mode & gone) return;
if (s_mart) {
if (!needbid) return;
}
else {
if (port->user->options & (u_bbs | u_expert))
outstr("Msg:\n");
else prtx(mm[1]);
}
msgfile(port->cmd, mfhs->next_msg);
if (!uloadm(port->cmd)) return;
/*
* If this is a Bulletin and has no BID,
* parse the headers and give it one.
*/
#ifndef MCH_AMIGA
if (!iscall(port->mmhs->to))
if (port->mmhs->type is 'B')
{
#else
/* Add BID or a MID to any kind of message */
if(*port->mmhs->bid == ' ') {
unbl(port->line, cport->user->call, ln_call);
#endif
a = port->line;
b = cport->user->call;
unbl(a, b, 6);
/* Default the BID as to coming from this BBS with our msg number. */
sprintf(tmp->scr, "%-u_%-s", mfhs->next_msg, port->line);
/* Now check the parsed headers if it came from another BBS. */
if (*orgbbs isnt '\0') sprintf(tmp->scr, "%s_%s", orgmsg, orgbbs);
if (!hasbid)
{
strncpy(port->mmhs->bid, tmp->scr, ln_bid);
hasbid = true;
}
else if (!matchn(port->mmhs->bid, tmp->scr, ln_bid)) putbid(false);
if (port->user->options & u_hold)
{
holdit = true;
port->mmhs->htype = 'U';
}
}
checkbid();
if (!needbid)
{
holdit = true;
port->mmhs->htype = 'D';
}
cremsg();
}
/*
* SM command, send a message to a distribution list.
*/
sndmlt()
{
register FILE *fl;
char fn[80];
register short first = true;
word tmpsize;
holdit = false;
fill(port->mmhs->bid, ' ', ln_bid);
if ((fl = fopen(port->fld[1], "r")) is NULL)
{ nofile(port->fld[1]); return; }
prtx(mm[0]);
get_title();
if (port->mode & gone) { fclose(fl); return; }
if (port->flds is 3) if (*port->fld[port->flds-1] is '$')
{
/* MCH_AMIGA */
if (*(port->fld[port->flds-1] + 1) /*isnt NULL*/)
{
strncpy(port->mmhs->bid, port->fld[port->flds-1] + 1, ln_bid);
hasbid = true;
}
}
prtx(mm[1]);
strncpy(port->mmhs->from, port->user->call, ln_call);
port->mmhs->ext = 0;
initmsg(false);
msgfile(fn, mfhs->next_msg);
if (!uloadm(fn)) { fclose(fl); return; }
tmpsize = filesize;
while (fgets(port->line, linelen, fl) isnt NULL)
{
parse();
if (!first)
{
port->mmhs->ext = 0;
initmsg(false);
msgfile(port->line, mfhs->next_msg);
copy(fn, port->line, false);
}
port->mmhs->type = port->opt2;
pcall(port->mmhs->to, port->fld[1]);
fill(port->mmhs->bbs, ' ', ln_call);
if(port->flds > 3) atfrom(2);
if(port->flds > 5) atfrom(4);
filesize = tmpsize;
#ifdef MCH_AMIGA
replace_bbs();
/* Put a BID or MID on this file if needed */
if( (port->mmhs->type is 'B') || (port->mmhs->type == 'P')) {
unbl(port->line, cport->user->call, ln_call);
/* Default the BID as to coming from this BBS with our msg number. */
sprintf(tmp->scr, "%-u_%-s", mfhs->next_msg, port->line);
strncpy(port->mmhs->bid, tmp->scr, ln_bid);
hasbid = true;
}
#endif
cremsg();
first = false;
}
fclose(fl);
}
/*
* M command, make a message from a file.
*/
makmsg()
{
#ifdef MCH_AMIGA
char *a,*b;
#endif
if ((port->fl = fopen(port->fld[2], "r")) is NULL)
{ nofile(port->fld[2]); return; }
fclose(port->fl);
#ifndef MCH_AMIGA
pfld();
#else
/* If there's an error in the command then return */
if(pfld() == 0)return;
#endif
if (port->mode & gone) return;
#ifdef MCH_AMIGA
/* Put a BID or MID on this file if needed */
if( (port->mmhs->type is 'B') || (port->mmhs->type == 'P')) {
unbl(port->line, cport->user->call, ln_call);
/* Default the BID as coming from this BBS with our msg number. */
sprintf(tmp->scr, "%-u_%-s", mfhs->next_msg, port->line);
strncpy(port->mmhs->bid, tmp->scr, ln_bid);
hasbid = true;
}
#endif
msgfile(port->line, mfhs->next_msg);
copy(port->fld[2], port->line, true);
cremsg();
}
/*
* MM command, make multiple messages from a file.
*/
makmlt()
{
register FILE *dfl;
char tnm[80];
holdit = false;
fill(port->mmhs->bid, ' ', ln_bid);
if ((port->fl = fopen(port->fld[2], "r")) is NULL)
{ nofile(port->fld[2]); return; }
fclose(port->fl);
if ((dfl = fopen(port->fld[1], "r")) is NULL)
{ nofile(port->fld[1]); return; }
strcpy(tnm, port->fld[2]);
if (port->flds is 4) if (*port->fld[port->flds-1] is '$')
{
/* MCH_AMIGA */
if (*(port->fld[port->flds - 1] + 1)/* isnt NULL*/)
{
strncpy(port->mmhs->bid, port->fld[port->flds-1] + 1, ln_bid);
hasbid = true;
}
}
prtx(mm[0]);
get_title();
if (port->mode & gone) { fclose(dfl); return; }
while (fgets(port->line, linelen, dfl) isnt NULL)
{
parse();
port->mmhs->type = port->opt2;
pcall(port->mmhs->to, port->fld[1]);
strncpy(port->mmhs->from, port->user->call, ln_call);
fill(port->mmhs->bbs, ' ', ln_call);
port->mmhs->ext = 0;
if (port->flds > 3) atfrom(2);
if (port->flds > 5) atfrom(4);
#ifdef MCH_AMIGA
/* Put a BID or MID on this file if needed */
if( (port->mmhs->type is 'B') || (port->mmhs->type == 'P')) {
unbl(port->line, cport->user->call, ln_call);
/* Default the BID as to coming from this BBS with our msg number. */
sprintf(tmp->scr, "%-u_%-s", mfhs->next_msg, port->line);
strncpy(port->mmhs->bid, tmp->scr, ln_bid);
hasbid = true;
}
replace_bbs();
#endif
initmsg(false);
msgfile(port->line, mfhs->next_msg);
copy(tnm, port->line, true);
cremsg();
}
fclose(dfl);
}
/*
* Mark stale messages.
*/
stale()
{
register word i;
register int ks;
register short ts;
for (i = mfhs->first; i and i <= mfhs->last; i++)
{
read_rec(mfl, i, (char *)port->mmhs);
switch(port->mmhs->type)
{
case 'T': ts = tstalen; ks = (s_flag & s_nkill); break;
case 'P': ts = tstaleu; ks = (s_flag & s_ukill); break;
default :
{
ts = tstaleb; ks = (s_flag & s_bkill); /* Max time period */
#ifdef MCH_AMIGA
/* If this is a bulletin and the lifetime is less than the default
then use the lifetime
*/
if(port->mmhs->type is 'B') {
if(port->mmhs->lifetime && (port->mmhs->lifetime < ts)) {
ts = port->mmhs->lifetime;
}
}
#endif
if (!(port->mmhs->stat & m_bull))
{
if (ddiff(port->mmhs->date, l_date, true) > tstale1) /* 1st time period */
if (port->mmhs->read < rstale1) ts = 0;
if (ddiff(port->mmhs->date, l_date, true) > tstale2) /* 2nd time period */
if (port->mmhs->read < rstale2) ts = 0;
if (ddiff(port->mmhs->date, l_date, true) > tstale3) /* 3rd time period */
if (port->mmhs->read < rstale3) ts = 0;
}
}
}
if (!(port->mmhs->stat & m_stale))
if (ddiff(port->mmhs->date, l_date, true) > ts)
{
if (ks and !(port->mmhs->stat & m_hold)) port->mmhs->stat setbit m_kill;
else port->mmhs->stat setbit m_stale;
write_rec(mfl, i, (char *)port->mmhs);
}
}
}
/*
* DW command: make wp message from user file.
*/
dwuser()
{
register int i;
register short first = true;
short doall;
if (*wpcall is ' ') return;
doall = port->flds is 2;
port->opt1 = 'S';
port->opt2 = 'P';
filesize = 0;
#ifdef MCH_AMIGA
check_user();
unlock_user();
#endif
for (i = 1; i <= ufhs->count; i++)
{
read_rec(ufl, i, (char *)tuser);
if ((tuser->state & u_home) and (tuser->state & u_zip))
if (doall or !(tuser->state & u_sent))
{
if (first)
{
first = false;
port->mmhs->type = 'P';
strncpy(port->mmhs->to, "WP ", ln_call);
strncpy(port->mmhs->from, cport->user->call, ln_call);
strncpy(port->mmhs->bbs, wpcall, ln_call);
strcpy(port->mmhs->title, "WP Update");
fill(port->mmhs->bid, ' ', ln_bid);
port->mmhs->ext = 0;
initmsg(false);
msgfile(port->line, mfhs->next_msg);
port->fl = fopen(port->line, "w");
fseek(port->fl, (long)RECSIZE, 0);
}
filesize += 72;
fprintf(port->fl, "On %6.6s %6.6s @ %6.6s zip %6.6s %-12.12s %-20.20s\n",
tuser->date, tuser->call, tuser->home_bbs, tuser->zip,
tuser->handle, tuser->qth);
tuser->state setbit u_sent;
if (s_flag & s_dv) begin_lock();
write_rec(ufl, i, (char *)tuser);
if (s_flag & s_dv)end_lock();
if (i is port->user->rn) port->user->state setbit u_sent;
}
}
if (!first)
{
fclose(port->fl);
chkhier();
cremsg();
}
}
/*
* E command, edit a message header.
*/
edmsg()
{
FILE *out;
char *a, *b;
#ifdef MCH_AMIGA
short life;
#endif
if (!findmsg(atoi(port->fld[1]))) { port->msg = mnmsg; return; }
while (*port->fld[0] isnt '\0')
{
prthdr(true, true);
#ifdef MCH_AMIGA
if(port->mmhs->type == 'B')
outstr("t(Y)pe, (S)tatus, (T)o, (F)rom, (B)bs, t(I)tle, bi(D), (L)ifetime\n");
else
#endif
outstr("t(Y)pe, (S)tatus, (T)o, (F)rom, (B)bs, t(I)tle, bi(D)\n");
getcmd();
if (port->mode & gone) return;
switch (*port->fld[0])
{
#ifdef MCH_AMIGA
case 'L' :
if(port->mmhs->type == 'B') {
life = atoi(port->fld[1]);
if((life >= 0) && (life < 256))port->mmhs->lifetime = life;
}
/* This 'L' command confuses prthdr(). So unconfuse it */
port->opt1 = ' ';
break;
#endif
case 'T' : pcall(port->mmhs->to, port->fld[1]); break;
case 'F' : pcall(port->mmhs->from, port->fld[1]); break;
case 'B' : edbbs(1); break;
case 'I' : if (*port->fld[1])
{
remnl(port->line);
strncpy(port->mmhs->title, port->line+2, mhtitl);
}
else *port->mmhs->title = '\0';
break;
case 'S' : switch(*port->fld[1])
{
case 'F' : port->mmhs->stat = m_fwd; break;
case 'H' : port->mmhs->stat = m_hold; break;
case 'N' : port->mmhs->stat = 0; break;
case 'O' : port->mmhs->stat = m_stale; break;
case 'Y' : port->mmhs->stat = m_read; break;
case '$' : port->mmhs->stat setbit m_bull; break;
}
break;
case 'Y' : if(*port->fld[1]) port->mmhs->type = *port->fld[1];
else port->mmhs->type = ' '; break;
case 'D' : if(*port->fld[1]) strncpy(port->mmhs->bid, port->fld[1], ln_bid);
else fill(port->mmhs->bid, ' ', ln_bid);
break;
}
}
wt_mmhs();
makehdr2();
if (*port->mmhs->bid isnt ' ')
{
checkbid();
if (needbid)
{
#ifdef MCH_AMIGA
lock_bid();
#endif
if ((out = fopen(bidfile,"a")) is NULL)
{
#ifdef MCH_AMIGA
unlock_bid();
#endif
port->msg = mcant; return;
}
a = port->cmd;
b = port->mmhs->bid;
unbl(a, b, ln_bid);
sprintf(port->line, "%4.4s%s\n", port->mmhs->date + 2, port->cmd);
if (s_flag & s_dv) begin_lock();
fputs(port->line, out);
if (s_flag & s_dv) end_lock();
fclose(out);
#ifdef MCH_AMIGA
unlock_bid();
#endif
}
}
}
/*
* ET command, edit an NTS traffic message header.
*/
edtfc()
{
register short ok;
if (!findmsg(atoi(port->fld[1]))) { port->msg = mnmsg; return; }
prthdr(true, true);
ok = (port->mmhs->type is 'T');
if (!ok) ok = ((port->mmhs->type is ' ') and matchn(port->mmhs->to, "NTS", 3));
if (!ok) { port->msg = mm[12]; return; }
prtx(mm[8]);
getcmd();
if (port->mode & gone) return;
if (port->flds) pcall(port->mmhs->to, port->fld[0]);
prtx(mm[9]);
getcmd();
if (port->mode & gone) return;
edbbs(0);
prtx(mm[10]);
getcmd();
if (port->mode & gone) return;
if (port->flds)
{
remnl(port->line);
strncpy(port->mmhs->title, port->line, mhtitl);
}
else if (*port->line is ' ') *port->mmhs->title = '\0';
prtx(mm[11]);
getcmd();
if (port->mode & gone) return;
if (port->flds) port->mmhs->type = *port->fld[0];
else if (*port->line is ' ') port->mmhs->type = ' ';
port->mmhs->stat = 0;
prthdr(true, true);
wt_mmhs();
makehdr2();
sprintf(port->line, "%u %-.6s %s",
port->mmhs->number, port->mmhs->to, port->mmhs->title);
log('M', 'E', port->opt2, port->line);
}
edbbs(f)
int f;
{
fill(port->mmhs->call, '\0', 92);
port->mmhs->ext = 0;
fill(port->mmhs->bbs, ' ', ln_call);
if(*port->fld[f])
{
pcall(port->mmhs->bbs, port->fld[f]);
if (strchr(port->fld[f], '.') is NULL) dodis();
else
{
port->mmhs->ext = 2;
strncpy(port->mmhs->call[0], port->fld[f], ln_hier);
}
if (port->mmhs->ext is 0) chkhier();
}
}
/*
* Check to see if bbs has match in STATES.MB file and add state code
* to hierarchical call.
*/
chkhier()
{
FILE *hier;
char hiercall[ln_call], bbs[ln_call+1], phier[ln_hier];
char *p;
#ifdef MCH_AMIGA
register char *q;
#endif
if (*port->mmhs->bbs is ' ') return;
if(( hier = fopen( stfile, "r")) is NULL) return;
while( fgets( tmp->scr, linelen, hier) isnt NULL)
{
pcall(hiercall, tmp->scr);
if( wcm(hiercall, port->mmhs->bbs))
{
#ifndef MCH_AMIGA
remnl(tmp->scr);
#endif
p = strchr(tmp->scr, '.');
unbl(bbs, port->mmhs->bbs, ln_call);
unbl(phier, p, ln_hier);
#ifdef MCH_AMIGA
/* If the hierarchical portion has .USA or .CAN on the end then add .NA */
for(q=phier;*q;q++);
p = q;
while((q > phier) && (*q != '.'))q--;
if(matchn(".USA",q,4) || matchn(".CAN",q,4)) {
strcpy(p,".NA");
}
#endif
port->mmhs->ext = 2;
fill( port->mmhs->call[0], '\0', 92);
sprintf( port->mmhs->call[0], "%s%s", bbs, phier);
fclose(hier);
return;
}
}
fclose(hier);
return;
}
/*
* Compress the bidfile by removing old bids
*/
cprs_bid()
{
FILE *bfl, *bbfl;
int x, yy, zz;
char biddate[7];
unlink(bbidfile);
rename(bidfile, bbidfile);
unlink(bidfile);
if ((bfl = fopen(bidfile, "a")) is NULL)
{
#ifndef MCH_AMIGA
printf("Error opening %s\n", bidfile);
#else
sprintf(tmpstr,"Error opening %s\n", bidfile);
ttputs(tmpstr);
#endif
return;
}
if ((bbfl = fopen(bbidfile, "r")) is NULL)
{
nofile(bbidfile);
return;
}
yy=0; zz=0;
#ifndef MCH_AMIGA
printf("Compressing bid file.......\n");
#else
/* NOTE that this routine is called at the same time as a GM is done and
there is already a lock on the whole system when this function executes
so there's no need to lock the BID semaphore.
*/
ttputs("Compressing bid file.......\n");
#endif
while (fgets(port->line, linelen, bbfl) isnt NULL)
{
fill (biddate, ' ', 6);
strncpy (biddate + 2, port->line, 4);
yy++;
if ((x = ddiff(biddate, l_date, false)) < 0)
x += 365;
if (x < bidnum)
{
fputs (port->line, bfl);
zz++;
}
}
#ifndef MCH_AMIGA
printf("There were %d records, now %d remain\n",yy,zz);
printf("Compression completed\n");
#else
sprintf(tmpstr,"There were %d records, now %d remain\n",yy,zz);
ttputs(tmpstr);
ttputs("Compression completed\n");
/* Get the BID semaphore and set the new length of file */
#endif
fclose (bfl);
fclose (bbfl);
}
#ifdef MCH_AMIGA
check_mail()
{
extern long get_mail();
lock_mail();
if(mfhs->count != get_mail()) {
close(mfl);
mfl = open(mbfile, O_RDWR | O_BINARY);
read_rec(mfl, 0, (char *)mfhs);
titles();
}
}
#endif